package com.css.fxfzdzzh.base.dict.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzdzzh.base.cache.CacheService;
import com.css.fxfzdzzh.base.dict.repository.DictItemRepository;
import com.css.fxfzdzzh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzdzzh.base.dict.service.DictItemService;
import com.css.fxfzdzzh.base.dict.viewobjects.DictEntityVo;
import com.css.fxfzdzzh.base.dict.viewobjects.DictItemQueryParams;
import com.css.fxfzdzzh.constants.FxfzConstants;
import com.css.fxfzdzzh.constants.YNEnum;
import com.css.fxfzdzzh.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.css.fxfzdzzh.constants.FxfzConstants.CACHE_SYS_KEY;

@Service
@Slf4j
public class DictItemImpl implements DictItemService {
    @Autowired
    DictItemRepository dictItemRepository;

    @Resource
    JdbcTemplate jdbcTemplate;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    CacheService cacheService;

    private static final String CACHE_DICT_ITEM_ID_KEY = "dictItemId:";
    private static final String CACHE_DICT_CODE_LIST_KEY = "dictCodeList:";
    @Override
    public JSONObject queryDictItems(DictItemQueryParams queryParams, int curPage, int pageSize){
        Page<DictItemEntity> itemEntities =  dictItemRepository.queryDictItems(queryParams,curPage,pageSize);
        JSONObject jsonObject = PlatformPageUtils.formatPageData(itemEntities);
        return jsonObject;
    }
    @Override
    public DictItemEntity saveDictItem(DictItemEntity itemEntity){
        String uuid = UUIDGenerator.getUUID();
        itemEntity.setDictItemId(uuid);
        itemEntity.setIsValid(YNEnum.Y.toString());
        itemEntity.setCreateUser(PlatformSessionUtils.getUserId());
        itemEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        dictItemRepository.saveDictItem(itemEntity);
        String dictCode = dictItemRepository.findDictCodeByDictItemId(itemEntity.getDictItemId());
        cacheService.delete(CACHE_SYS_KEY + CACHE_DICT_CODE_LIST_KEY + dictCode);
        return itemEntity;
    }
    @Override
    public DictItemEntity updateDictItem(DictItemEntity itemEntity){
        itemEntity.setUpdateUser(PlatformSessionUtils.getUserId());
        itemEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        dictItemRepository.saveDictItem(itemEntity);
        String dictCode = dictItemRepository.findDictCodeByDictItemId(itemEntity.getDictItemId());
        cacheService.delete(CACHE_SYS_KEY + CACHE_DICT_ITEM_ID_KEY + itemEntity.getDictItemId());
        cacheService.delete(CACHE_SYS_KEY + CACHE_DICT_CODE_LIST_KEY + dictCode);
        return itemEntity;
    }
    @Override
    public DictItemEntity getDictItem(String id){
        DictItemEntity itemEntity = null;
        itemEntity = (DictItemEntity) cacheService.get(CACHE_SYS_KEY + CACHE_DICT_ITEM_ID_KEY + id);
        if (PlatformObjectUtils.isEmpty(itemEntity) ) {
            itemEntity = dictItemRepository.findById(id);
            cacheService.set(CACHE_SYS_KEY + CACHE_DICT_ITEM_ID_KEY + id, itemEntity);
        }
        return itemEntity;
    }
    @Transactional(rollbackFor = Exception.class )
    @Override
    public void deleteDictItems(List<String> ids){
        deleteDictCache(ids);
        dictItemRepository.delete(ids);
    }
    @Override
    public boolean validateDictItemCode(String dictId,String dictItemId,String dictItemCode){
        boolean isValid = false;
        DictItemEntity dte = dictItemRepository.findOneByDictItemCodeAndDictId(dictItemCode,dictId);
        if(PlatformObjectUtils.isEmpty(dte)){
            isValid = false;
        }else if(dte.getDictItemId().equals(dictItemId)){
            isValid = true;
        }
        return isValid;
    }
    @Transactional(rollbackFor = Exception.class )
    @Override
    public void updateDictItems(List<String> ids,String type){
        List<DictItemEntity> dictEntitys = dictItemRepository.findAllById(ids);
        deleteDictCache(ids);
        for(DictItemEntity dictEntity:dictEntitys){
            if("1".equals(type)){
                dictEntity.setIsValid(YNEnum.Y.toString());
            }else{
                dictEntity.setIsValid(YNEnum.N.toString());
            }
            dictEntity.setUpdateUser(PlatformSessionUtils.getUserId());
            dictEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
            dictItemRepository.saveDictItem(dictEntity);
        }
    }

    private void deleteDictCache(List<String> ids){
        List<String> dictCacheKeys = new ArrayList<String>();
        List<DictItemEntity> dictItems = dictItemRepository.findAllById(ids);
        List<String> dictCodes = dictItemRepository.findDictCodeByDictItemIds(ids);
        if(PlatformObjectUtils.isNotEmpty(dictItems)){
            for(DictItemEntity dictItem:dictItems){
                dictCacheKeys.add(CACHE_SYS_KEY + CACHE_DICT_ITEM_ID_KEY + dictItem.getDictItemId());
            }
        }
        if(PlatformObjectUtils.isNotEmpty(dictCodes)){
            for(String dictCode:dictCodes){
                dictCacheKeys.add(CACHE_SYS_KEY + CACHE_DICT_CODE_LIST_KEY + dictCode);
            }
        }
        cacheService.delete(dictCacheKeys);
    }

    @Override
    public List<DictEntityVo> getDictItemByDictId(String dictCode) {
        StringBuilder sql = new StringBuilder("select dict.dict_id,dict.dict_name,dict.dict_code,item.dict_item_code,item.dict_item_name from sys_dict dict,sys_dict_item item " +
                " where dict.dict_id = item.dict_id and dict.is_valid='1' and item.is_valid='1'");
        if(StringUtils.isNotBlank(dictCode)){
            sql.append(" and dict.dict_code ='").append(dictCode).append("'");
        }
        List<DictEntityVo> vos = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(DictEntityVo.class));
        Map<String, List<DictEntityVo>> map = buildDictMap(vos);
        //分类放到redis
        for(Map.Entry<String,List<DictEntityVo>> m : map.entrySet()){
            redisTemplate.opsForValue().set(FxfzConstants.CACHE_SYS_KEY +  m.getKey(),JSONObject.toJSONString(m.getValue()));
        }
        return vos;
    }

    /**
     *
     * @param dictEntityVoList
     * @return java.util.List<com.css.fxfzdzzh.base.dict.viewobjects.DictEntityVo>
     * @desc  字典数据构建map结构
     */
    private Map<String, List<DictEntityVo>> buildDictMap(List<DictEntityVo> dictEntityVoList){
        Map<String, List<DictEntityVo>> map = new HashMap<String,List<DictEntityVo>>(dictEntityVoList.size());
        List<DictEntityVo> vos = new ArrayList<>();
        for(DictEntityVo dictEntityVo : dictEntityVoList){
            if(!map.containsKey(dictEntityVo.getDictCode())){
                //如果map没有添加过对应的key则添加
                vos.add(dictEntityVo);
                map.put(dictEntityVo.getDictCode(),vos);
                vos = new ArrayList<>();
                continue;
            }
            //如果map有添加过对应的key则取出value值加入新的值再放入map中
            List<DictEntityVo> dictEntityVos = map.get(dictEntityVo.getDictCode());
            dictEntityVos.add(dictEntityVo);
            map.put(dictEntityVo.getDictCode(),dictEntityVos);
        }
        return map;
    }

    @Override
    public List<DictEntityVo> getDictItemByDictDirId(String dictDirId) {
        return dictItemRepository.getDictItemByDictDirId(dictDirId);
    }
}
